package com.mijie.homi.api;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mijie.core.Status;
import com.mijie.exception.DeleteLastOneRecordException;
import com.mijie.exception.RecordNotFoundException;
import com.mijie.exception.UpdateFailException;
import com.mijie.homi.common.constant.HomiStatusCode;
import com.mijie.homi.common.domain.mood.Mood;
import com.mijie.homi.common.domain.timeline.TimelineEvent;
import com.mijie.homi.common.domain.topic.Topic;
import com.mijie.homi.common.domain.user.User;
import com.mijie.homi.common.util.HomiUtil;
import com.mijie.homi.domain.topic.TopicOptions;
import com.mijie.homi.service.mood.MoodService;
import com.mijie.homi.service.timeline.TimelineService;
import com.mijie.homi.service.topic.TopicService;
import com.mijie.homi.service.user.FriendService;
import com.mijie.homi.service.user.UserService;
import com.mijie.homi.util.ServerHelper;
import com.mijie.util.IOUtil;

@Controller
@RequestMapping("/timeline")
public class TimelineApi {

	@Autowired
	private TimelineService service;
	@Autowired
	private MoodService moodService;
	@Autowired
	private TopicService topicService;
	@Autowired
	private FriendService friendService;
	@Autowired
	private UserService userService;
	
	
	private Logger logger = Logger.getLogger(TimelineApi.class);
	
	@RequestMapping(value="/segment",method=RequestMethod.GET)
	public @ResponseBody void segment(Integer userId,Integer sinceId,Integer maxId,int count,
			HttpServletRequest request,HttpServletResponse response){
		Integer requester  = ServerHelper.getUserId(request);
		if(userId==null) userId = requester;
		List<TimelineEvent> list = service.timelineSegment(userId, sinceId, maxId, count);
		Status status = new Status(request,response);
		JSONArray result = new JSONArray();
		if(!list.isEmpty()){
			List<Long> moodIdList = new ArrayList<Long>();
			List<Integer> topicIdList = new ArrayList<Integer>();
			for(TimelineEvent event : list){
				if(event.getEventType()==TimelineEvent.TYPE_MOOD){
					moodIdList.add(event.getEventId());
				}else{
					topicIdList.add((int) event.getEventId());
				}
			}
			
			Map<Long,Mood> moodMap = null;
			Map<Integer,Topic> topicMap = null;
			if(!moodIdList.isEmpty()) moodMap = moodService.listMoodMapByIds(moodIdList);
			if(!topicIdList.isEmpty()) topicMap = topicService.listTopicMapByIds(topicIdList);
			
			JSONObject eventJson = null;
			JSONObject eventDetailJson = null;
			Mood mood = null;
			Topic topic = null;
			boolean isFriend = false;
			if(userId!=requester)
				isFriend = friendService.isFriend(userId, requester);
			
			User owner = userService.getUserById(userId);
			Set<Long> viewPrivilege = null;
			if(!moodIdList.isEmpty())
				viewPrivilege = moodService.listMoodIdByViewPrivlege(requester,moodIdList);
			for(TimelineEvent event : list){
				eventJson = new JSONObject();
				eventJson.accumulate("id", event.getId());
				eventJson.accumulate("eventId", event.getEventId());
				eventJson.accumulate("eventType", event.getEventType());
				eventJson.accumulate("createAt", event.getCreateAt());
				if(event.getEventType()==TimelineEvent.TYPE_MOOD){
					mood = moodMap.get(event.getEventId());
					if(mood==null){
						logger.info("timeline segment id:"+event.getId()+" eventType:"+event.getEventType()+" eventId:"+event.getEventId()+" event not found!");
						continue;
					}
					eventDetailJson = JSONObject.fromObject(mood);
					eventDetailJson.remove("id");
					eventDetailJson.remove("keyword");
					eventDetailJson.remove("userId");
					eventDetailJson.put("isFriend", isFriend);
					eventDetailJson.put("viewPrivilege", viewPrivilege.contains(mood.getId()));
					eventDetailJson.put("authorGender", owner.getGender());
					eventDetailJson.put("authorNickName", owner.getNickName());
					eventDetailJson.put("authorAvatar", HomiUtil.getRealUrl(owner.getAvatar()));
					eventDetailJson.remove("createAt");
				}else{
					topic = topicMap.get((int)event.getEventId());
					if(topic==null){
						logger.info("timeline segment id:"+event.getId()+" eventType:"+event.getEventType()+" eventId:"+event.getEventId()+" event not found!");
						continue;
					}
					eventDetailJson = JSONObject.fromObject(topic);
					eventDetailJson.remove("author");
					eventDetailJson.remove("id");
					eventDetailJson.put("authorGender", owner.getGender());
					eventDetailJson.put("authorNickName", owner.getNickName());
					eventDetailJson.put("authorAvatar", HomiUtil.getRealUrl(owner.getAvatar()));
					List<TopicOptions> optionsList = topicService.getOptions(topic.getId());
					JSONArray options = JSONArray.fromObject(optionsList);
					eventDetailJson.accumulate("options", options);
				}
				eventJson.accumulate("eventDetail", eventDetailJson);
				result.add(eventJson);
			}
		}
		status.setResult(result);
		status.write();
	}
	
	@RequestMapping(value="/event/delete",method=RequestMethod.POST)
	public @ResponseBody void delete(HttpServletRequest request,HttpServletResponse response) 
			throws IOException{
		Status status = new Status(request,response);
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		try {
			StringBuilder msg = new StringBuilder();
			int succ = service.deleteTimelineEvent(msg,ServerHelper.getUserId(request), json.getInt("id"));
			if(succ==0) status.setCode(HomiStatusCode.DATABASE_ERROR);
			else status.setResult(msg.toString());
		} catch (RecordNotFoundException e) {
			logger.error(e.getMessage(), e);
			status.setCode(HomiStatusCode.RECORD_NOT_FOUND);
		} catch (DeleteLastOneRecordException e) {
			logger.error(e.getMessage(), e);
			status.setCode(HomiStatusCode.LAST_ONE_RECORD);
		} catch (UpdateFailException e) {
			logger.error(e.getMessage(), e);
			status.setCode(HomiStatusCode.DATABASE_ERROR);
		}
		status.write();
	}
}
